package we_chat_group

import (
	"errors"
	"fmt"
	"github.com/eatmoreapple/openwechat"
	"os"
	"regexp"
	"server/src/global"
	"server/src/model"
	"server/src/model/request"
	"server/src/server"
	"server/src/utils"
	"strconv"
	"strings"
	"time"
)

var (
	jiaoIns  = []string{"^[1-4][1-4]/[1-9]\\d*", "^[1-4][1-4]角[1-9]\\d*", "^单[1-9]\\d*", "^双[1-9]\\d*", "^大[1-9]\\d*", "^小[1-9]\\d*"}
	zhengIns = []string{"^[1-4]正[1-9]\\d*", `^[1-4]/\d*`}
	fanIns   = []string{"^[1-4]牛\\d*", "^[1-4]番\\d*"}
	nianIns  = []string{"^[1-4]念[1-4][1-9]\\d*", "^[1-4]-[1-4][1-9]\\d*"}

	shangfenIns = []string{"上[1-9]\\d*"}
	xiafenIns   = []string{"下[1-9]\\d*"}

	wuxiaoIns = []string{"^\\d"}
)

func robotInstruct(msg *openwechat.Message, sender *openwechat.User, groupUser *model.WeChatGroupUser) error {
	msgData := strings.ReplaceAll(msg.Content, " ", "")
	currentTime := time.Now()
	if match, rule := matchString(msgData, jiaoIns); match {
		//执行角的函数
		if global.BG_GAME_RUN_WAIT_TIME <= 0 || (currentTime.Hour() < 7 || currentTime.Hour() > 24) {
			bettingFailNotOpenTimeRes(msg, sender)
			return nil
		}
		err, userScore := jiaoInsfunc(msgData, rule, groupUser.Id)
		fmt.Println("__rule__", rule)
		if err != nil {
			if err.Error() == INVALIDINSTRUCTION {
				fmt.Println("无效指令")
				invalidInstructionRes(msg, sender)
				return err
			} else if err.Error() == NOTSCORE {
				fmt.Println("积分不足")
				bettingNotScoreRes(msg, sender, userScore)
				return err
			}
			fmt.Println("执行角失败", err)
			bettingFailRes(msg, sender)
			return errors.New("执行角失败==" + err.Error())
		} else {
			//查找用户本期所有答案
			currentBettingInfo, _ := server.ServerGroupUser.QueryBgCurrentBetting(groupUser.Id, global.BG_CURRENT_ANSWERID)
			bettingSuccessRes(msg, sender, userScore, currentBettingInfo)
		}
	} else if match, rule := matchString(msgData, zhengIns); match {
		//执行正的函数
		if global.BG_GAME_RUN_WAIT_TIME <= 0 || (currentTime.Hour() < 7 || currentTime.Hour() > 24) {
			bettingFailNotOpenTimeRes(msg, sender)
			return nil
		}
		err, userScore := zhengInsfunc(msgData, rule, groupUser.Id)
		fmt.Println("__rule__", rule)
		if err != nil {
			if err.Error() == INVALIDINSTRUCTION {
				fmt.Println("无效指令")
				invalidInstructionRes(msg, sender)
				return err
			} else if err.Error() == NOTSCORE {
				fmt.Println("积分不足")
				bettingNotScoreRes(msg, sender, userScore)
				return err
			}
			fmt.Println("执行正失败", err)
			bettingFailRes(msg, sender)
			return errors.New("执行正失败==" + err.Error())
		} else {
			//查找用户本期所有答案
			currentBettingInfo, _ := server.ServerGroupUser.QueryBgCurrentBetting(groupUser.Id, global.BG_CURRENT_ANSWERID)
			bettingSuccessRes(msg, sender, userScore, currentBettingInfo)
		}
	} else if match, rule := matchString(msgData, fanIns); match {
		//执行番的函数
		if global.BG_GAME_RUN_WAIT_TIME <= 0 || (currentTime.Hour() < 7 || currentTime.Hour() > 24) {
			bettingFailNotOpenTimeRes(msg, sender)
			return nil
		}
		err, userScore := fanInsfunc(msgData, rule, groupUser.Id)
		fmt.Println("__rule__", rule)
		if err != nil {
			if err.Error() == INVALIDINSTRUCTION {
				fmt.Println("无效指令")
				invalidInstructionRes(msg, sender)
				return err
			} else if err.Error() == NOTSCORE {
				fmt.Println("积分不足")
				bettingNotScoreRes(msg, sender, userScore)
				return err
			}
			fmt.Println("执行番失败", err)
			bettingFailRes(msg, sender)
			return errors.New("执行番失败==" + err.Error())
		} else {
			//查找用户本期所有答案
			currentBettingInfo, _ := server.ServerGroupUser.QueryBgCurrentBetting(groupUser.Id, global.BG_CURRENT_ANSWERID)
			bettingSuccessRes(msg, sender, userScore, currentBettingInfo)
		}
	} else if match, rule := matchString(msgData, nianIns); match {
		//执行念的函数
		if global.BG_GAME_RUN_WAIT_TIME <= 0 || (currentTime.Hour() < 7 || currentTime.Hour() > 24) {
			bettingFailNotOpenTimeRes(msg, sender)
			return nil
		}
		err, userScore := nianInsfunc(msgData, rule, groupUser.Id)
		fmt.Println("__rule__", rule)
		if err != nil {
			if err.Error() == INVALIDINSTRUCTION {
				fmt.Println("无效指令")
				invalidInstructionRes(msg, sender)
				return err
			} else if err.Error() == NOTSCORE {
				fmt.Println("积分不足")
				bettingNotScoreRes(msg, sender, userScore)
				return err
			}
			fmt.Println("执行念失败", err)
			bettingFailRes(msg, sender)
			return errors.New("执行念失败==" + err.Error())
		} else {
			//查找用户本期所有答案
			currentBettingInfo, _ := server.ServerGroupUser.QueryBgCurrentBetting(groupUser.Id, global.BG_CURRENT_ANSWERID)
			bettingSuccessRes(msg, sender, userScore, currentBettingInfo)
		}
	} else if match, _ := matchString(msgData, shangfenIns); match {
		//上方
		index := strings.Index(msgData, "上")
		integral, err := strconv.Atoi(msgData[index+3:])
		err = server.ServerGroupUser.ApplyDivision(groupUser.Id, groupUser.Gid, float64(integral))
		if err != nil {
			appleFailRes(msg, sender, "上分["+strconv.Itoa(integral)+"]失败")
			return err
		}
		appleSuccessRes(msg, sender, "申请上分["+strconv.Itoa(integral)+"]收到，等待管理员审核")
	} else if match, _ := matchString(msgData, xiafenIns); match {
		//下方
		index := strings.Index(msgData, "下")
		integral, err := strconv.Atoi(msgData[index+3:])
		err = server.ServerGroupUser.ApplyDivision(groupUser.Id, groupUser.Gid, 0-float64(integral))
		if err != nil {
			appleFailRes(msg, sender, "下分["+strconv.Itoa(integral)+"]失败")
			return err
		}
		appleSuccessRes(msg, sender, "申请下分["+strconv.Itoa(integral)+"]收到，等待管理员审核")
	} else if msgData == "2" {
		//查看番薯
		//番薯图片
		fanshuImgUrl := global.GVL_CFG.Local.HeadUrl + strconv.Itoa(global.BG_CURRENT_ANSWERID) + "_fanshu.png"
		if _, err := os.Stat(fanshuImgUrl); err != nil {
			utils.Screenshot(fanshuImgUrl, 220, 80, 780, 570)
		}
		fanshuimg, _ := os.Open(fanshuImgUrl)
		defer fanshuimg.Close()
		msg.ReplyImage(fanshuimg)

		//历史记录图片
		historyImgUrl := global.GVL_CFG.Local.HeadUrl + strconv.Itoa(global.BG_CURRENT_ANSWERID) + "_history.png"
		if _, err := os.Stat(historyImgUrl); err != nil {
			utils.Screenshot(historyImgUrl, 1250, 80, 500, 300)
		}
		historyimg, _ := os.Open(historyImgUrl)
		defer historyimg.Close()
		msg.ReplyImage(historyimg)
	} else if msgData == "4" {
		//回水
		returnScore, historyReturnScore, err := server.ServerGroupUser.GetReturnWater(groupUser)
		if err != nil {
			appleFailRes(msg, sender, "回水失败")
			return err
		}
		appleSuccessRes(msg, sender, fmt.Sprintf("回水成功\n本次💰%.2f\n已回💰%.2f\n积分💰%.2f\n",
			returnScore, historyReturnScore, groupUser.SumScore+returnScore))
	} else if msgData == "5" {
		//今日详情
		//获取今日盈亏
		err, phase := server.ServerGuess.QueryTodayPhase(groupUser.Id)
		if err != nil {
			phase = 0.00
		}
		todaysDetails(msg, sender, groupUser, phase)
	} else if msgData == "7" {
		//取消订单
		if err := server.ServerGuess.UserCancelBgBetting(groupUser.Id, global.BG_CURRENT_ANSWERID); err != nil {
			appleFailRes(msg, sender, "本期无猜题记录")
			return err
		}
		appleSuccessRes(msg, sender, "取消竞猜成功")
	} else if match, _ := matchString(msgData, wuxiaoIns); match {
		//无效指令
		fmt.Println("无效指令", msgData)
		invalidInstructionRes(msg, sender)
	}
	return nil
}

func matchString(s string, patterns []string) (bool, string) {
	for _, pattern := range patterns {
		match, _ := regexp.MatchString(pattern, s)
		if match {
			return true, pattern
		}
	}
	return false, ""
}

func jiaoInsfunc(msgData string, rule string, uid int) (error, float64) {
	betNums := make([]int, 2)
	integral := 0
	var err error
	switch {
	case rule == jiaoIns[0]:
		index := strings.Index(msgData, "/")
		betNums[0] = int(msgData[0] - '0')
		betNums[1] = int(msgData[1] - '0')
		integral, err = strconv.Atoi(msgData[index+1:])
	case rule == jiaoIns[1]:
		index := strings.Index(msgData, "角")
		betNums[0] = int(msgData[0] - '0')
		betNums[1] = int(msgData[1] - '0')
		integral, err = strconv.Atoi(msgData[index+3:])
	case rule == jiaoIns[2]:
		index := strings.Index(msgData, "单")
		betNums[0] = 1
		betNums[1] = 3
		integral, err = strconv.Atoi(msgData[index+3:])
	case rule == jiaoIns[3]:
		index := strings.Index(msgData, "双")
		betNums[0] = 2
		betNums[1] = 4
		integral, err = strconv.Atoi(msgData[index+3:])
	case rule == jiaoIns[4]:
		index := strings.Index(msgData, "大")
		betNums[0] = 1
		betNums[1] = 2
		integral, err = strconv.Atoi(msgData[index+3:])
	case rule == jiaoIns[5]:
		index := strings.Index(msgData, "小")
		betNums[0] = 3
		betNums[1] = 4
		integral, err = strconv.Atoi(msgData[index+3:])
	default:
		return errors.New(INVALIDINSTRUCTION), 0
	}
	bettingInfo := &request.UserBettings{
		AnswerId:      global.BG_CURRENT_ANSWERID,
		Num:           betNums,
		Integral:      float64(integral),
		PlayingMethod: global.BG_JIAO,
	}
	fmt.Println("下注信息", bettingInfo)
	//查看用户积分
	userInfo := server.ServerGroupUser.QueryGroupUserScore(uid)
	if userInfo.SumScore < bettingInfo.Integral {
		fmt.Println("积分不够")
		return errors.New(NOTSCORE), userInfo.SumScore
	}
	if err := server.ServerGuess.UserBgBetting(uid, bettingInfo); err != nil {
		fmt.Println("下注角失败")
		return err, userInfo.SumScore
	}
	return err, userInfo.SumScore - bettingInfo.Integral
}

func zhengInsfunc(msgData string, rule string, uid int) (error, float64) {
	betNums := make([]int, 1)
	integral := 0
	var err error
	switch {
	case rule == zhengIns[0]:
		index := strings.Index(msgData, "正")
		betNums[0] = int(msgData[0] - '0')
		integral, err = strconv.Atoi(msgData[index+3:])
	case rule == zhengIns[1]:
		index := strings.Index(msgData, "/")
		betNums[0] = int(msgData[0] - '0')
		integral, err = strconv.Atoi(msgData[index+1:])
	default:
		return errors.New(INVALIDINSTRUCTION), 0
	}
	bettingInfo := &request.UserBettings{
		AnswerId:      global.BG_CURRENT_ANSWERID,
		Num:           betNums,
		Integral:      float64(integral),
		PlayingMethod: global.BG_ZHENG,
	}
	fmt.Println("下注信息", bettingInfo)
	//查看用户积分
	userInfo := server.ServerGroupUser.QueryGroupUserScore(uid)
	if userInfo.SumScore < bettingInfo.Integral {
		fmt.Println("积分不够")
		return errors.New(NOTSCORE), userInfo.SumScore
	}
	if err := server.ServerGuess.UserBgBetting(uid, bettingInfo); err != nil {
		fmt.Println("下注正失败")
		return err, userInfo.SumScore
	}
	return err, userInfo.SumScore - bettingInfo.Integral
}

func fanInsfunc(msgData string, rule string, uid int) (error, float64) {
	betNums := make([]int, 1)
	integral := 0
	var err error
	switch {
	case rule == fanIns[0]:
		index := strings.Index(msgData, "牛")
		betNums[0] = int(msgData[0] - '0')
		integral, err = strconv.Atoi(msgData[index+3:])
	case rule == fanIns[1]:
		index := strings.Index(msgData, "番")
		betNums[0] = int(msgData[0] - '0')
		integral, err = strconv.Atoi(msgData[index+3:])
	default:
		return errors.New(INVALIDINSTRUCTION), 0
	}
	bettingInfo := &request.UserBettings{
		AnswerId:      global.BG_CURRENT_ANSWERID,
		Num:           betNums,
		Integral:      float64(integral),
		PlayingMethod: global.BG_FAN,
	}
	fmt.Println("下注信息", bettingInfo)
	//查看用户积分
	userInfo := server.ServerGroupUser.QueryGroupUserScore(uid)
	if userInfo.SumScore < bettingInfo.Integral {
		fmt.Println("积分不够")
		return errors.New(NOTSCORE), userInfo.SumScore
	}
	if err := server.ServerGuess.UserBgBetting(uid, bettingInfo); err != nil {
		fmt.Println("下注番失败")
		return err, userInfo.SumScore
	}
	return err, userInfo.SumScore - bettingInfo.Integral
}

func nianInsfunc(msgData string, rule string, uid int) (error, float64) {
	betNums := make([]int, 2)
	integral := 0
	var err error
	switch {
	case rule == nianIns[0]:
		index := strings.Index(msgData, "念")
		betNums[0] = int(msgData[0] - '0')
		betNums[1] = int(msgData[index+3] - '0')
		integral, err = strconv.Atoi(msgData[index+4:])
	case rule == nianIns[1]:
		index := strings.Index(msgData, "-")
		betNums[0] = int(msgData[0] - '0')
		betNums[1] = int(msgData[index+1] - '0')
		integral, err = strconv.Atoi(msgData[index+2:])
	default:
		return errors.New(INVALIDINSTRUCTION), 0
	}
	bettingInfo := &request.UserBettings{
		AnswerId:      global.BG_CURRENT_ANSWERID,
		Num:           betNums,
		Integral:      float64(integral),
		PlayingMethod: global.BG_NIAN,
	}
	fmt.Println("下注信息", bettingInfo)
	//查看用户积分
	userInfo := server.ServerGroupUser.QueryGroupUserScore(uid)
	if userInfo.SumScore < bettingInfo.Integral {
		fmt.Println("积分不够")
		return errors.New(NOTSCORE), userInfo.SumScore
	}
	if err := server.ServerGuess.UserBgBetting(uid, bettingInfo); err != nil {
		fmt.Println("下注念失败")
		return err, userInfo.SumScore
	}
	return err, userInfo.SumScore - bettingInfo.Integral
}
